home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1995 January
/
Simtel - 10000 MSDOS Shareware Programs (Walnut Creek)(January 1995)(Disc 2).ISO
/
disc2
/
diskutil
/
du.c
< prev
next >
Wrap
C/C++ Source or Header
|
1987-05-14
|
7KB
|
394 lines
/*
* du.c:
*
* `Du' is a disk usage utility which computes the diskusage of
* all the files in a directory and it's subdirectories.
*
* This utility is comparable with the UNIX du program.
*
* Usage: du [-s] [-a] [d:path ...]
*
* Option -s (/s) does not show subdirectories (short listing).
* Option -a (/a) shows size of all the files.
*
* Copyright: Tom Vijlbrief, Baarn, The Netherlands
* Date: Fri May 8 13:53:29 GMT+1:00 1987
*
* This program may be distributed freely for non commercial purposes
* and with this Copyright notice unchanged.
*/
/*
* Compilation must be performed with structure packing and larger stack:
* Microsoft C 4.00: -Zp -F2000
*/
#include <stdio.h>
#include <string.h>
#include <dos.h>
#include <io.h>
#include <direct.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>
#define BLOCK_SIZE 512
#define ALL_FILES (0x1 | 0x2 | 0x4 | 0x10 |0x20)
#define DIRECTORIES (0x10)
#define NAME_LEN 8
#define EXT_LEN 3
#define MAX_CWD 256
typedef unsigned char byte;
typedef struct {
byte FF;
byte zero_5[5];
byte attribute;
byte drive;
char name[NAME_LEN];
char extension[EXT_LEN];
unsigned cur_block;
unsigned rec_size;
unsigned fs_low;
unsigned fs_high;
unsigned date;
byte unused2[10];
byte cur_record;
unsigned ran_low;
unsigned ran_high;
} ext_fcb;
char *get_first(char *, int, ext_fcb *);
char *get_next(ext_fcb *);
long scan();
byte sector[BLOCK_SIZE];
int cluster_size;
int a_flag;
int s_flag;
int in_tree;
ext_fcb return_fcb;
main(argc, argv)
int argc;
char *argv[];
{
char *option_p;
static char cur_cwd[MAX_CWD];
int drive_nr;
int cur_drive;
while (argc > 1) {
option_p= *++argv;
if (*option_p == '-' || *option_p == '/') {
for (option_p++; *option_p; option_p++) {
switch (*option_p) {
case 'a':
a_flag++;
break;
case 's':
s_flag++;
break;
default:
fprintf(stderr,
"Unknown option: %c\n", *option_p);
fprintf(stderr,
"Usage: du [-s] [-a] [d:path ...]\n");
exit(1);
}
}
argc--;
} else
break;
}
if (argc == 1) {
cluster_size= comp_cluster(get_drive());
scan();
} else {
for (; argc > 1; argc--, argv++) {
cur_drive= get_drive();
getcwd(cur_cwd, MAX_CWD - 1);
if ((*argv)[1] == ':')
set_drive(tolower((*argv)[0]) - 'a');
if (chdir(*argv) != 0) {
perror(*argv);
set_drive(cur_drive);
continue;
}
cluster_size= comp_cluster(get_drive());
scan();
set_drive(cur_drive);
if (chdir(cur_cwd) != 0) {
perror(cur_cwd);
exit(1);
}
in_tree= 0;
}
}
}
static struct stat the_stat;
static char cwd[MAX_CWD];
long scan()
{
char *p;
long file_size;
long disk_use;
int tree_flag;
ext_fcb the_fcb;
char pattern[NAME_LEN + EXT_LEN + 2];
tree_flag= in_tree;
disk_use= 0;
strcpy(pattern, "????????.???");
p= get_first(pattern, ALL_FILES, &the_fcb);
for (; p != NULL; p= get_next(&the_fcb)) {
if (strcmp(p, ".. . ") == 0
|| strcmp(p, ". . ") == 0)
continue;
if (stat(p, &the_stat) != 0) {
perror(p);
exit(1);
}
if (the_stat.st_mode & S_IFDIR) {
if (a_flag) {
printf("%s\n", p);
printf("========================\n");
}
chdir(p);
in_tree= 1;
disk_use+= scan();
chdir("..");
} else {
disk_use+= ((file_size= the_stat.st_size) + (cluster_size - 1))
/ cluster_size * cluster_size;
if (a_flag) {
printf("%s: %10ld\n", p, file_size);
}
}
}
if (a_flag)
printf("========================\n");
if (!s_flag || !tree_flag)
printf("Disk Usage : %10ld (%s)\n", disk_use,
getcwd(cwd, MAX_CWD - 1));
if (a_flag)
printf("\n");
return(disk_use);
}
/*
* get_first returns the first_name in a directory matching the
* pattern (e.g. ????????.OBJ) and attribute
*/
char *get_first (pattern, attribute, fcb_p)
char *pattern;
int attribute;
ext_fcb *fcb_p;
{
set_dta(&return_fcb);
strncpy(fcb_p->name, pattern, NAME_LEN);
strncpy(fcb_p->extension, pattern + NAME_LEN + 1, EXT_LEN);
fcb_p->attribute= attribute;
fcb_p->FF= 0xFF;
fcb_p->drive= get_drive() + 1;
if ((bdos(0x11, (int) fcb_p, 0) & 0xFF) == 0) {
strncpy(pattern, return_fcb.name, NAME_LEN);
strncpy(pattern + NAME_LEN + 1, return_fcb.extension, EXT_LEN);
return(pattern);
} else
return(NULL);
}
char *get_next(fcb_p)
ext_fcb *fcb_p;
{
static char pattern[]= "12345678.123";
set_dta(&return_fcb);
if ((bdos(0x12, (int) fcb_p, 0) & 0xFF) == 0) {
strncpy(pattern, return_fcb.name, NAME_LEN);
strncpy(pattern + NAME_LEN + 1, return_fcb.extension, EXT_LEN);
pattern[NAME_LEN + EXT_LEN + 1]= '\0';
return(pattern);
} else {
return(NULL);
}
}
/*
* `set_drive' changes the current drive. (A = 0, etc).
*/
int set_drive(drive_nr)
int drive_nr;
{
return(bdos(0xE, drive_nr, 0) & 0xFF);
}
/*
* `get_drive' returns the number of the current drive. (A = 0, etc).
*/
int get_drive()
{
return(bdos(0x19, 0, 0) & 0xFF);
}
set_dta(p)
ext_fcb *p;
{
return(bdos(0x1A, (int) p, 0) & 0xFF);
}
#define DISK 0x13
#define READ_SECT 0x2
#define RESET_DISK 0x0
#define FLOP_RETRIES 3
int readsect(buffer, drive, head, cyl, sector, n_sectors)
char *buffer;
unsigned int drive;
unsigned int head;
unsigned int cyl;
unsigned int sector;
unsigned int n_sectors;
{
int result;
int retries;
int max_retries;
union REGS inregs,
outregs;
struct SREGS segregs;
segread(&segregs);
segregs.es= segregs.ds;
if (drive < 0x80)
max_retries= FLOP_RETRIES;
else
max_retries= 1;
for (retries= 0; retries < max_retries; retries++) {
if (drive < 0x80) {
inregs.h.ah= RESET_DISK;
inregs.h.dl= drive;
int86(DISK, &inregs, &outregs);
}
inregs.h.ah= READ_SECT;
inregs.x.bx= (unsigned) buffer;
inregs.h.dl= drive;
inregs.h.dh= head;
inregs.h.ch= cyl;
inregs.h.cl= sector | ((cyl & ~0xFF) >> 2);
inregs.h.al= n_sectors;
result= (unsigned) int86x(DISK, &inregs, &outregs, &segregs) >> 8;
if (outregs.x.cflag)
continue;
else
break;
}
if (retries == max_retries)
return(-result);
else
return(0);
}
int comp_cluster(drive_nr)
int drive_nr;
{
int nr_sectors;
int head_nr;
int high_head;
int sector_nr;
if (drive_nr > 1)
drive_nr+= 0x80 - 2;
high_head= max_head(drive_nr);
for (head_nr= 0; head_nr <= high_head; head_nr++) {
for (sector_nr= 1; sector_nr <= 8; sector_nr++) {
if (readsect(sector, drive_nr, head_nr, 0, sector_nr, 1) != 0) {
fprintf(stderr, "Cannot read bootblock from disk\n");
exit(1);
}
if (sector[0] == 0xEB)
break;
}
if (sector[0] == 0xEB)
break;
}
if (sector_nr > 8 || (nr_sectors= sector[13]) > 16) {
nr_sectors= 4;
fprintf(stderr,
"Unknown bootblock, clustersize of 4 sectors assumed\n");
}
if (nr_sectors == 0)
nr_sectors= 2;
return(nr_sectors * BLOCK_SIZE);
}
#define GET_PARAM 0x8
int max_head(drive)
unsigned int drive;
{
union REGS inregs,
outregs;
inregs.h.ah= GET_PARAM;
inregs.h.dl= drive;
int86(DISK, &inregs, &outregs);
if (outregs.x.cflag)
return(0);
else
return(outregs.h.dh);
}